package com.linkoog.devtools.intellij.ui.button;

import java.util.List;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
import com.intellij.openapi.keymap.KeymapUtil;
import com.intellij.openapi.ui.OptionAction;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.openapi.util.Weighted;
import com.intellij.ui.UIBundle;
import com.intellij.ui.components.OptionButtonUI;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nls;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

public class JBOptionButton extends JButton implements Weighted {
    private static final CustomShortcutSet DEFAULT_SHOW_POPUP_SHORTCUT = new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.ALT_MASK | InputEvent.SHIFT_MASK));

    private static final String PROP_OPTIONS = "OptionActions";
    private static final String PROP_OPTION_TOOLTIP  = "OptionTooltip";
    private static final String PLACE  = "ActionPlace";

    private Action[] options;
    private String optionTooltipText;
    private boolean addSeparator = true;
    private boolean selectFirstItem = true;
    private Color popupBackgroundColor;
    private int showPopupYOffset = 6;
    private JBPopupHandler popupHandler;

    public JBOptionButton(Action action, Action[] options) {
        super(action);
        this.options = options;
    }

    public void setOptions(List<AnAction> actions) {
        if (actions != null) {
            options = actions.stream().map(AnActionWrapper::new).toArray(Action[]::new);
        } else {
            options = null;
        }
    }

    public void setOptionTooltipText(String optionTooltipText) {
        String oldValue = this.optionTooltipText;
        this.optionTooltipText = optionTooltipText;
        firePropertyChange(PROP_OPTION_TOOLTIP, oldValue, optionTooltipText);
    }

    public boolean isSimpleButton() {
        return options == null || options.length == 0;
    }

    public void setAddSeparator(boolean addSeparator) {
        this.addSeparator = addSeparator;
    }

    public void setSelectFirstItem(boolean selectFirstItem) {
        this.selectFirstItem = selectFirstItem;
    }

    public void setPopupBackgroundColor(Color popupBackgroundColor) {
        this.popupBackgroundColor = popupBackgroundColor;
    }

    public void setShowPopupYOffset(int showPopupYOffset) {
        this.showPopupYOffset = showPopupYOffset;
    }

    public void setPopupHandler(JBPopupHandler popupHandler) {
        this.popupHandler = popupHandler;
    }

    @Override
    public String getUIClassID() {
        return "OptionButtonUI";
    }

    @Override
    public OptionButtonUI getUI() {
        return (OptionButtonUI) super.getUI();
    }

    @Override
    public double getWeight() {
        return 0.5;
    }

    public void togglePopup() {
        getUI().togglePopup();
    }

    public void showPopup(Action actionToSelect, boolean ensureSelection) {
        getUI().showPopup(actionToSelect, ensureSelection);
    }

    public void closePopup() {
        getUI().closePopup();
    }

    @Deprecated
    @ApiStatus.ScheduledForRemoval
    public void updateOptions(Action[] options) {
        this.options = options;
    }

    public static CustomShortcutSet getDefaultShowPopupShortcut() {
        return DEFAULT_SHOW_POPUP_SHORTCUT;
    }

    public static String getDefaultTooltip() {
        return UIBundle.message("option.button.tooltip.shortcut.text",
                KeymapUtil.getFirstKeyboardShortcutText(getDefaultShowPopupShortcut()));
    }

    public interface JBPopupHandler {
        void handle(JBPopup popup);
    }

    private static class AnActionWrapper extends AbstractAction {
        public AnActionWrapper(AnAction action) {
            putValue(OptionAction.AN_ACTION, action);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            // do nothing
        }
    }
}
